package com.youlu.campus.service.universitytimetable;

import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.common.utils.TimeUtils;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.ActivityTaskInfo;
import com.youlu.campus.entity.DailyLearning;
import com.youlu.campus.entity.UserCaReceiveHistory;
import com.youlu.campus.entity.UserDailyLearning;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.UserParticipateActivityInfo;
import com.youlu.campus.entity.VO.res.UserCaHonorRes;
import com.youlu.campus.entity.VO.res.UserSignInInviteInfoRes;
import com.youlu.campus.entity.VO.res.UserSignInRes;
import com.youlu.campus.entity.WechatMiniUserPO;
import com.youlu.campus.entity.ca.UserCa;
import com.youlu.campus.entity.clock.dto.UserSignInfoDTO;
import com.youlu.campus.entity.domain.PlayBillDomain;
import com.youlu.campus.entity.enums.TaskBizType;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.activity.ActivityTaskService;
import com.youlu.campus.service.activity.UserParticipateActivityInfoService;
import com.youlu.campus.service.ca.UserCaService;
import com.youlu.campus.service.ca.impl.CaCertificateConfigService;
import com.youlu.campus.service.clock.UserClockService;
import com.youlu.campus.service.course.convert.LiteHomeCourseConvert;
import com.youlu.campus.service.learning.DailyLearningService;
import com.youlu.campus.service.timetable.UserTimetableService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UserSignInService {


    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ActivityTaskService activityTaskService;

    @Autowired
    private ActivityService activityService;

    @Autowired
    private CaCertificateConfigService caCertificateConfigService;

    @Autowired
    private DailyLearningService dailyLearningService;

    @Autowired
    private UserCaService userCaService;

    @Autowired
    private UserParticipateActivityInfoService userParticipateActivityInfoService;

    @Autowired
    private UserTimetableService userTimetableService;

    @Autowired
    private UserClockService userClockService;

    @Autowired
    private LiteHomeCourseConvert liteHomeCourseConvert;

    private final static String USER_SIGN_IN_LABEL = "已累计学习%s天";


    public UserSignInInviteInfoRes getUserSignInviteInfo(UserPO currentUser, String activityId) {
        String userId = currentUser.getId();
        String openId = currentUser.getOpenId();
        String unionId = currentUser.getUnionId();
        log.info("【用户打卡信息】activityId:{},userId:{}", activityId, userId);
        ActivityInfo activityInfo = this.activityService.findOne(activityId);
        if (Objects.isNull(activityInfo)) {
            throw new BusinessException("活动不存在");
        }
        UserSignInInviteInfoRes userSignInInviteInfo = new UserSignInInviteInfoRes();
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.LEARNING);
        Query query =
                new Query().addCriteria(Criteria.where("userId").is(userId).and("taskId").is(activityTaskInfo.getId()).and("activityId").is(activityId));
        long userSignInCount = this.mongoTemplate.count(query, UserDailyLearning.class);
        userSignInInviteInfo.setUserSignInDay((int) userSignInCount);
        userSignInInviteInfo.setUserSignInDayLabel(String.format(USER_SIGN_IN_LABEL, userSignInCount));
        query = new Query().addCriteria(Criteria.where("openId").is(openId).and("unionId").is(unionId));
        WechatMiniUserPO user = this.mongoTemplate.findOne(query, WechatMiniUserPO.class);
        if (Objects.nonNull(user)) {
            userSignInInviteInfo.setNickName(user.getNickName());
            userSignInInviteInfo.setAvatarUrl(user.getAvatarUrl());
        }
        userSignInInviteInfo.setCourseNameList(userTimetableService.getLocalCourseNameList(userId, activityId));
        if (!"timetable".equals(activityInfo.getType())) {
            Date now = new Date();
            DailyLearning dailyLearning = dailyLearningService.getDailyLearning(activityId, activityTaskInfo.getId(), now);
            if (StringUtils.isNotBlank(dailyLearning.getPosterImgUrl())) {
                userSignInInviteInfo.setInviteBackGroundImageUrl(dailyLearning.getPosterImgUrl());
            }
        } else {
            query = new Query();
            query.addCriteria(Criteria.where("activityId").is(activityId));
            query.addCriteria(Criteria.where("taskBizType").is(TaskBizType.INVITE));
            ActivityTaskInfo taskInfo = this.mongoTemplate.findOne(query, ActivityTaskInfo.class);
            if (Objects.nonNull(taskInfo)) {
                PlayBillDomain playBill = taskInfo.getPlayBill();
                if (Objects.nonNull(playBill)) {
                    if (ArrayUtils.isNotEmpty(playBill.getPlayBillImageUrls()))
                        userSignInInviteInfo.setInviteBackGroundImageUrl(playBill.getPlayBillImageUrls()[0]);
                }
            }
        }
        return userSignInInviteInfo;
    }

    public boolean hasReceive(String userId, String activityId, String caType, String caLevel) {
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        query.addCriteria(Criteria.where("caType").is(caType));
        query.addCriteria(Criteria.where("caLevel").is(caLevel));
        query.addCriteria(Criteria.where("activityId").is(activityId));
        return this.mongoTemplate.exists(query, UserCaReceiveHistory.class);
    }

    public UserSignInRes getUserSignInfo(UserPO currentUser, String activityId) {
        String userId = currentUser.getId();
        log.info("【用户打卡信息】activityId:{},userId:{}", activityId, userId);
        ActivityInfo activityInfo = activityService.findOne(activityId);
        ActivityTaskInfo activityTaskInfo = activityTaskService.find(activityId, TaskBizType.LEARNING);
        if (Objects.isNull(activityTaskInfo)) {
            throw new BusinessException("未配置打卡任务");
        }
        UserSignInRes userSignIn = new UserSignInRes();
        userSignIn.setHeaderImageUrl(activityInfo.getHeaderImageUrl());
        userSignIn.setHeaderImageUrl2(activityInfo.getHeaderImageUrl2());
        userSignIn.setRecieveCaDetail(activityInfo.getRecieveCaDetail());
        userSignIn.setSignInTipImgUrl(activityTaskInfo.getSignInTipImgUrl());
        long userSignInCount = 0;
        Integer signInDay = activityTaskInfo.getSignInDay();
        boolean isContinueSign = "continuous-daka".equals(activityInfo.getType());
        if (isContinueSign) {
            ActivityTaskInfo inviteTask = activityTaskService.find(activityId, TaskBizType.INVITE);
            if (Objects.isNull(inviteTask)) {
                throw new BusinessException("未配邀请任务");
            }
            userSignIn.setTaskId(inviteTask.getId());
            UserSignInfoDTO record = userClockService.getSignInfo(activityId, userId, LocalDate.now());
            userSignInCount = record.getUserContinueSignInDay();
            userSignIn.setUserContinueSignInDay(record.getUserContinueSignInDay());
            userSignIn.setCurrentDateSignIn(record.getCurrentDateSignIn());
            userSignIn.setUserSignInDay(record.getUserSignInDay());
            userSignIn.setSignInDay(signInDay - record.getUserContinueSignInDay());
            userSignIn.setSignUpTime(record.getSignUpTime());
            userSignIn.setUserReSignInDay(record.getUserReSignInDay());
            userSignIn.setShowJoinNum(activityInfo.getShowJoinNum());
            if (activityInfo.getShowJoinNum()) {
                Long totalJoinNum = liteHomeCourseConvert.getJoinNum(activityId, activityInfo.getInitJoinNum(), activityInfo.getRandomInitJoinNum(), true);
                userSignIn.setTotalJoinNum(totalJoinNum > 100000 ? "10万+人已报名" : totalJoinNum + "人已报名");
            }
            List<UserCaHonorRes> caList = caCertificateConfigService.findByActivityId(activityId);
            boolean caReceive = userSignInCount >= signInDay;
            userSignIn.setCaReceive(caReceive);
            if (CollectionUtils.isNotEmpty(caList)) {
                UserCaHonorRes userCa = caList.stream().findFirst().orElse(null);
                if (Objects.nonNull(userCa)) {
                    userSignIn.setHasReceive(hasReceive(userId, activityId, userCa.getCaType(), userCa.getCaLevel()));
                    userSignIn.setCaType(userCa.getCaType());
                    userSignIn.setCaLevel(userCa.getCaLevel());
                    if (!userSignIn.getHasReceive() && caReceive) {
                        UserCa userCa2 = new UserCa();
                        userCa2.setCertificateActivityConfigId(userCa.getCertificateActivityConfigId());
                        userCa2.setCertificateName(userCa.getCertificateName());
                        userCa2.setCaType(userCa.getCaType());
                        userCa2.setCaLevel(userCa.getCaLevel());
                        userCa2.setActivityId(activityId);
                        userCa2.setMoneyType("3");
                        userCa2.setActivityName(activityInfo.getName());
                        userCa2.setTaskBizType("qa");
                        userCa2.setUserId(userId);
                        userCa2.setScore(0D);
                        UserParticipateActivityInfo userParticipateActivityInfo = userParticipateActivityInfoService.findByUserIdActivityId(userId, activityId);
                        if (Objects.nonNull(userParticipateActivityInfo)) {
                            userCa2.setUniversityId(userParticipateActivityInfo.getUniversityId());
                            userCa2.setName(userParticipateActivityInfo.getName());
                            userCa2.setUniversityName(userParticipateActivityInfo.getUniversityName());
                            userCa2.setMobile(userParticipateActivityInfo.getMobile());
                            userCa2.setGrade(userParticipateActivityInfo.getGrade());
                        }
                        userCa2.setPlatform(currentUser.getCurrentPlatform());
                        userCa2.setAppId(currentUser.getAppId());
                        userCaService.create(userCa2);
                    }
                }
            }
        } else {
            Query query =
                    new Query().addCriteria(Criteria.where("userId").is(userId).and("taskId").is(activityTaskInfo.getId()).and("activityId").is(activityId));
            userSignInCount = this.mongoTemplate.count(query, UserDailyLearning.class);
            userSignIn.setUserSignInDay((int) userSignInCount);
            log.info("【用户打卡信息】activityId:{},userId:{},userSignInCount:{}", activityId, userId, userSignInCount);
            int signInCount = Math.subtractExact(signInDay, (int) userSignInCount);
            log.info("【用户打卡信息】activityId:{},userId:{},userSignInCount:{},剩余打卡天数:{}", activityId, userId, userSignInCount,
                    signInCount);
            userSignIn.setSignInDay(signInCount);
        }
        if (!isContinueSign && userSignInCount >= signInDay) {
            userSignIn.setCaReceive(Boolean.TRUE);
            List<UserCaHonorRes> caList = caCertificateConfigService.findByActivityId(activityId);
            if (CollectionUtils.isNotEmpty(caList)) {
                UserCaHonorRes userCa = caList.stream().findFirst().orElse(null);
                if (Objects.nonNull(userCa)) {
                    userSignIn.setCaType(userCa.getCaType());
                    userSignIn.setCaLevel(userCa.getCaLevel());
                    UserCa userCa2 = new UserCa();
                    userCa2.setCertificateActivityConfigId(userCa.getCertificateActivityConfigId());
                    userCa2.setCertificateName(userCa.getCertificateName());
                    userCa2.setCaType(userCa.getCaType());
                    userCa2.setCaLevel(userCa.getCaLevel());
                    userCa2.setActivityId(activityId);
                    userCa2.setMoneyType("3");
                    userCa2.setActivityName(activityInfo.getName());
                    userCa2.setTaskBizType("qa");
                    userCa2.setUserId(userId);
                    userCa2.setScore(0D);
                    UserParticipateActivityInfo userParticipateActivityInfo = userParticipateActivityInfoService.findByUserIdActivityId(userId, activityId);
                    if (Objects.nonNull(userParticipateActivityInfo)) {
                        userCa2.setUniversityId(userParticipateActivityInfo.getUniversityId());
                        userCa2.setName(userParticipateActivityInfo.getName());
                        userCa2.setUniversityName(userParticipateActivityInfo.getUniversityName());
                        userCa2.setMobile(userParticipateActivityInfo.getMobile());
                        userCa2.setGrade(userParticipateActivityInfo.getGrade());
                    }
                    userCa2.setPlatform(currentUser.getCurrentPlatform());
                    userCa2.setAppId(currentUser.getAppId());
                    userCaService.create(userCa2);
                }
            }
        }
        Date date = new Date();
        Date dayStart = TimeUtils.getDayStartTime(date);
        Date dayEnd = TimeUtils.getDayEndTime(date);
        Query query = new Query().addCriteria(Criteria.where("activityId").is(activityId).and("taskId").is(activityTaskInfo.getId()).andOperator(
                Criteria.where("dayTime").lte(dayEnd), Criteria.where("dayTime").gte(dayStart)));
        DailyLearning dailyLearning = mongoTemplate.findOne(query, DailyLearning.class);
        if (Objects.nonNull(dailyLearning)) {
            userSignIn.setSignInImgUrl(dailyLearning.getImageUrl());
            userSignIn.setDailyLearningId(dailyLearning.getId());
        }
        if (!isContinueSign) {
            UserDailyLearning userDailyLearning = dailyLearningService.getUserDailyLearning(activityId, activityTaskInfo.getId(),
                    currentUser.getId(), date);
            if (Objects.nonNull(userDailyLearning)) {
                log.error(":>>> 用户:{} 已经签到:{} ,不要重复签到", userId, activityId);
                userSignIn.setCurrentDateSignIn(Boolean.TRUE);
            }
        }
        return userSignIn;
    }
}
